#include <iostream.h>
#include <stdio.h>
int x = 4, y = 5; // 外部对象
void main()       // 主程序开始
{                 //第1程序块开始
    {
        int x = 1; // 第2程序块开始
        {
            int x = 2; // 第3程序块开始
            {
                int x = 3;                      //第4程序块开始
                printf("x=%d,&x=%#p\n", x, &x); // 输出第4块的x和存储地址
                printf("y=%d,&y=%#p\n", y, &y); // 输出外部的y和存储地址
            }                                   //第4程序块结束
            printf("x=%d,&x=%#p\n", x, &x);     // 输出第3块的x和存储地址
            printf("y=%d,&y=%#p\n", y, &y);     // 输出外部的y和存储地址
        }                                       // 第3程序块结束
        printf("x=%d,&x=%#p\n", x, &x);         // 输出第2块的x和存储地址
        printf("y=%d,&y=%#p\n", y, &y);         // 输出外部的y和存储地址
    }                                           // 第2程序块结束
    printf("x=%d,&x=%#p\n", x, &x);             // 输出外部的x和存储地址
    printf("y=%d,&y=%#p\n", y, &y);             // 输出外部的y和存储地址
} //主程序结束

/*
内存地址由系统分配，不同机器为变量分配的地址大小虽然可以不一样，但都必须给它分配地址。
    存储类型 类型 变量名列表；

C定义的常用存储类型有4种，即auto、extern、static、register，分别称为自动型、外部型、静态型和寄存器型。

1. 块结构 {} 用在同一个函数内，遵循变量屏蔽原则。
    在块内可以对变量进行定义，在块内定义的变量其作用域仅限于块内。
    若块内定义与块外或外部定义具有相同的变量名，则它们是没有关系的。
2. 自动型变量
    在函数内部定义的变量称为自动型变量，它们的作用域定义在函数内部。
    自动型变量定义以关键字auto标识，但在函数内部可以省略
    编译程序为自动型变量动态分配存储空间
    自动型变量既不能被任何其他函数所引用，也不能保存其值。
    两个函数之间要实现自动型变量的值传递，只有通过函数的参数来传递。
3.外部型变量
    外部型变量就是在任何函数的外部定义的变量，它可以被程序中的所有函数所引用。
    外部型变量实质上具有“全局型”定义，它的作用域是整个程序。
    引用外部变量主要有以下3个原因。
        1）因为外部型变量在整个程序中都可存取，所以它提供了在函数之间作为数据通信的另一种方法。
        2）外部型变量与初始化有关，有时需要由外部变量提供初始值。
        3）外部型变量是永久性的，在一次函数调用之后到下一次函数调用之前的期间内，能够保持它的值不变。

4. 静态变量
    静态变量可以是内部静态变量或外部静态变量。
    在函数外部定义的就称为外部静态变量，在函数内部定义的就称为内部静态变量。

    内部静态变量类似于自动型变量，它的作用域限于定义内部静态变量的函数内部，
    但不同于自动型变量的是，内部静态变量是始终存在并占有内存单元，
    其初值也只是在进入时赋值一次，而不是在进入函数时被建立或退出函数时被消除。
    静态变量只初始化一次，这就使它的初值总保持为上一个值

    一般来说函数是外部型的，但同时也可将函数定义为静态的，
    被定义为外部静态的函数只能被该函数所在的文件中的其他函数调用，
    而不能被其他文件中的函数调用。


    通过将变量或函数定义为外部静态型，
    可以将一个文件中的一些函数和数据隐藏起来，不允许别的文件存取。

5.寄存器型变量
    一个寄存器型变量的定义形式为
        register int x;
        register char c;
    这种只适用于自动型变量和函数的形式参数声明，
    不适用外部变量和静态变量，也不能用“&”运算符取它们的地址。
    另外，目前已经不推荐这种方式。

6.volatile型变量
    volatile影响编译器编译的结果。
    如果没有volatile关键字，则编译器可能优化读取和存储。
    即在本次线程内，当读取一个变量时，为提高存取速度，
    编译器优化时会先将变量读取到一个寄存器中，
    以后再取变量值时，就直接从寄存器中取值。
*/